package com.maybach.workflow.core.processor.impl;


import com.maybach.workflow.common.api.WorkFlowContext;
import com.maybach.workflow.common.api.enums.FlowStateEnum;
import com.maybach.workflow.common.api.enums.NodeTypeEnum;
import com.maybach.workflow.common.api.node.BaseNode;
import com.maybach.workflow.common.api.node.JoinNode;
import com.maybach.workflow.common.model.FlowTaskDO;
import com.maybach.workflow.core.service.TaskService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Created by houenxun on 15/8/13.
 */
public class JoinProcessor extends AbstractProcessor {
    @Autowired
    private TaskService taskService;

    @Override
    public boolean runIn(WorkFlowContext workFlowContext) {

        JoinNode nextTaskNode = (JoinNode) workFlowContext.getThisNode();
        //判断join任务是否已经存在
        FlowTaskDO joinTask = flowRepository.getTaskByType(workFlowContext.getThisFlow().getId(), nextTaskNode.getName(), NodeTypeEnum.join.name());
        if (joinTask == null) {
            joinTask = new FlowTaskDO();
            joinTask.setDisplayName(nextTaskNode.getDisplayName());
            // TODO parent
            joinTask.setParentTaskId(super.getParentTaskId(workFlowContext));
            joinTask.setTaskName(nextTaskNode.getName());
            joinTask.setTaskState(FlowStateEnum.init.getStatus());
            joinTask.setFlowId(workFlowContext.getThisFlow().getId());
            joinTask.setTaskType(nextTaskNode.getNodeType().name());
            flowRepository.createFlowTask(joinTask);

        }
        workFlowContext.setThisTask(joinTask);
        this.runOut(workFlowContext);
        return true;
    }

    @Override
    public void runOut(WorkFlowContext workFlowContext) {
        simpleRunOut(workFlowContext);
    }

    @Override
    public List<BaseNode> getNextNodes(WorkFlowContext workFlowContext) {
        return super.getCommonNextNodes(workFlowContext);
    }

    // TODO 算法有问题 还是暂时沿用
    protected void simpleRunOut(WorkFlowContext workFlowContext) {
        FlowTaskDO thisTask = workFlowContext.getThisTask();
        List<FlowTaskDO> taskList = flowRepository.getFlowTasksByFlowIdAndType(workFlowContext.getThisFlow().getId(), NodeTypeEnum.task.name());
        boolean isFinished = true;
        if (CollectionUtils.isEmpty(taskList)) {
            isFinished = true;
        } else {
            for (FlowTaskDO flowTaskDO : taskList) {
                // 访问记录，每一个结点只访问一次，防止流程变成图后，陷入死循环
                Set<String> visitSet = new HashSet<String>();
                if (taskService.isChildNode(workFlowContext.getThisFlowChain(), flowTaskDO.getTaskName(), workFlowContext.getThisNode().getName(), visitSet)) {
                    isFinished = false;
                    break;
                }
            }
        }
        if (isFinished) {
            flowRepository.delFlowTaskById(thisTask.getId());
            super.noPersistRunOut(workFlowContext);
        }
    }




}
